function DomEventWrapper(dayDom) {
    this._dom = dayDom;
    this._lastVisitPoint = null;
    this._mouseoutCallback = this._mouseoverCallback = this._clickCallback
     = this._mouseupCallback = this._mousedownCallback = this._mouseenterCallback = function() { };
    this._domJObjectLoaded = false;
}

DomEventWrapper.prototype = {    
    _LoadDomJObject: function() {
        this._dom = $(this._dom)
        this._cWidth = this._dom.width();
        this._cHeight = this._dom.height();
        this._domJObjectLoaded = true;
    },

    _calcCellPosition: function() {
        if (!this._domJObjectLoaded) {
            this._LoadDomJObject();
        }

        var cOffset = this._dom.offset();
        this._cLeft = cOffset.left;
        this._cTop = cOffset.top;
        this._cRight = this._cLeft + this._cWidth;
        this._cBottom = this._cTop + this._cHeight;
    },

    _containsPoint: function(point) {
        this._calcCellPosition();
        return this._isOnDom(this._cLeft, this._cRight, this._cTop, this._cBottom, point);
    },

    _isOnDom: function(left, right, top, bottom, point) {
        return left <= point.pageX && point.pageX <= right && top <= point.pageY && point.pageY <= bottom;
    },

    _updateLastVisitPoint: function(e) {
        this._lastVisitPoint = { pageX: e.pageX, pageY: e.pageY };
    },

    touch: function(e) {
        if (this._lastVisitPoint) {
            var lastVisitPointIn = this._containsPoint(this._lastVisitPoint);
            var currentVisitIn = this._containsPoint(e);

            if (lastVisitPointIn && !currentVisitIn) {
                this._mouseoutCallback(this._dom, e);
            }

            if (!lastVisitPointIn && currentVisitIn) {
                this._mouseenterCallback(this._dom, e);
            }

            if (currentVisitIn) {
                this._mouseoverCallback(this._dom, e);
            }
        }

        this._updateLastVisitPoint(e);
    },
    mousedown: function(e) {
        if (this._containsPoint(e)) {
            this._mousedownCallback(this._dom, e);
        }
    },
    mouseup: function(e) {
        if (this._containsPoint(e)) {
            this._mouseupCallback(this._dom, e);
        }
    },
    onMouseover: function(callback) {
        this._mouseoverCallback = callback;
    },
    onMouseout: function(callback) {
        this._mouseoutCallback = callback;
    },
    onMouseenter: function(callback) {
        this._mouseenterCallback = callback;
    },
    onMousedown: function(callback) {
        this._mousedownCallback = callback;
    },
    onMouseup: function(callback) {
        this._mouseupCallback = callback;
    }
};


function CalendarBodyEventWrapper(wrapDom, dayDoms, noteDoms) {
    this._dayEventWrappers = this._createEventWrappers(dayDoms);
    this._noteEventWrappers = this._createEventWrappers(noteDoms);
    this._bindEvents(wrapDom);
}
CalendarBodyEventWrapper.prototype = {
    _createEventWrappers: function(doms) {
        return $.map(doms, function(dom) {
            return new DomEventWrapper(dom);
        });
    },

    _touch: function(e) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.touch(e);
        });
    },
    _mousedown: function(e) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.mousedown(e);
        });
    },
    _mouseup: function(e) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.mouseup(e);
        });
    },
    _bindEvents: function(wrapDom) {
        var me = this;
        wrapDom.mousemove(function(e) {
            me._touch(e);
            //return false to prevent highlight dom on IE
            if ($.browser.msie) {
                return false;
            }
        });
        wrapDom.mouseout(function(e) {
            me._touch(e);
        });
        wrapDom.mousedown(function(e) {
            me._mousedown(e);
        });
        wrapDom.mouseup(function(e) {
            me._mouseup(e);
        });
    },
    onMouseover: function(callback) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.onMouseover(callback);
        });
    },
    onMouseout: function(callback) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.onMouseout(callback);
        });
    },
    onMousedown: function(callback) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.onMousedown(callback);
        });
    },
    onMouseup: function(callback) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.onMouseup(callback);
        });
    },
    onMouseenter: function(callback) {
        this._dayEventWrappers.foreach(function(wrapper) {
            wrapper.onMouseenter(callback);
        });
    }
};

